package com.gzz.orchid.common.core.util;


import java.security.SecureRandom;
import java.util.Collection;
import java.util.Formatter;
import java.util.Random;
import java.util.random.RandomGenerator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 字符串工具类
 *
 * @author higmd
 */
public class StringUtil {
    // 定义字符集
    public static final String ALPHANUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    public static final String ALPHABETIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    public static final String NUMERIC = "0123456789";
    /**
     * 检查指定的字符串是否为空。
     * <ul>
     * <li>SysUtils.isEmpty(null) = true</li>
     * <li>SysUtils.isEmpty("") = true</li>
     * <li>SysUtils.isEmpty("   ") = true</li>
     * <li>SysUtils.isEmpty("abc") = false</li>
     * </ul>
     *
     * @param value 待检查的字符串
     * @return true/false
     */
    public static boolean isEmpty(String value) {
        int strLen;
        if (value == null || (strLen = value.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((!Character.isWhitespace(value.charAt(i)))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 对象不为空
     */
    public static boolean isNotEmpty(Object value) {
        if (value == null) {
            return false;
        }
        return !isEmpty(value.toString());
    }

    /**
     * 手机号码脱敏
     */
    public static String desensitizationMobile(String str) {
        if (ValidatorUtil.isMobileNumber(str)) {
            return str.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
        }
        return str;
    }

    /**
     * 身份证号码脱敏
     */
    public static String desensitizationUid(String str) {
        if (ValidatorUtil.isUid(str)) {
            return str.replaceAll("(\\d{4})\\d{8}(\\w{6})", "$1********$2");
        }
        return str;
    }

    /**
     * byte数组转16进制
     * 高位在前
     */
    public static String byteToHex(byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result.toUpperCase();
    }

    /**
     * 生成随机字符串
     */
    public static String randomString(int length) {
        RandomGenerator random = RandomGenerator.getDefault();
        StringBuffer sb = new StringBuffer();
        random
                .ints(length, 0, ALPHANUMERIC.length())
                .forEach(i -> sb.append(ALPHANUMERIC.charAt(i)));

        return sb.toString();
    }

    private static final Random RANDOM8 = new SecureRandom();
    public static String randomAlphaNumeric(int length) {
        return IntStream.range(0, length)
                .map(i -> RANDOM8.nextInt(ALPHANUMERIC.length()))
                .mapToObj(randomIndex -> String.valueOf(ALPHANUMERIC.charAt(randomIndex)))
                .collect(Collectors.joining());
    }
    public static String randomAlpha(int length) {
        return IntStream.range(0, length)
                .map(i -> RANDOM8.nextInt(ALPHABETIC.length()))
                .mapToObj(randomIndex -> String.valueOf(ALPHABETIC.charAt(randomIndex)))
                .collect(Collectors.joining());
    }
    public static String randomNumeric(int length) {
        return IntStream.range(0, length)
                .map(i -> RANDOM8.nextInt(NUMERIC.length()))
                .mapToObj(randomIndex -> String.valueOf(NUMERIC.charAt(randomIndex)))
                .collect(Collectors.joining());
    }
    /**
     * 生成随机字符串(JDK8以前)
     */
    private static final Random RANDOM = new Random();
    public static String generateAlphaNumeric(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int randomIndex = RANDOM.nextInt(ALPHANUMERIC.length());
            char randomChar = ALPHANUMERIC.charAt(randomIndex);
            sb.append(randomChar);
        }
        return sb.toString();
    }
    public static String generateAlpha(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int randomIndex = RANDOM.nextInt(ALPHABETIC.length());
            char randomChar = ALPHABETIC.charAt(randomIndex);
            sb.append(randomChar);
        }
        return sb.toString();
    }
    public static String generateNumeric(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int randomIndex = RANDOM.nextInt(NUMERIC.length());
            char randomChar = NUMERIC.charAt(randomIndex);
            sb.append(randomChar);
        }
        return sb.toString();
    }

    /**
     * 判断对象包含是否为数字
     */
    public static boolean isNumeric(Object value) {
        return switch (value) {
            case null -> Boolean.TRUE;
            case Object[] valueArray -> Stream.of(valueArray)
                    .allMatch(item -> item instanceof Number);
            case Collection<?> valueCollection -> valueCollection
                    .stream()
                    .allMatch(item -> item instanceof Number);
            default -> value instanceof Number;
        };
    }
    /**
     * 驼峰转下划线
     */
    public static String camelToSnake(String camelCase) {
        if (camelCase == null || camelCase.length() == 0) {
            return camelCase;
        }
        if (camelCase.length() > 1 && Character.isUpperCase(camelCase.charAt(0))){
            camelCase = Character.toLowerCase(camelCase.charAt(0)) + camelCase.substring(1);
        }
        return camelCase
                .replaceAll("(?<!^)([A-Z])", "_$1")
                .toLowerCase();
    }

    /**
     * 转义字符
     */
     public static String escape(String sql){
         return sql.replaceAll("'", "''");
     }

     /**
      * 获取字符串中首次出现的字符的位置
      */
     public static Integer startChar(String str, String specialChar){
         Matcher matcher = Pattern.compile(specialChar).matcher(str);
         if (matcher.find()) {
             System.out.println("Found match at index: " + matcher.start());
             return matcher.start();
         }
         return -1;
     }
}
